/*
 *  Copyright (C) 2010:
 *                 Buzzanca Marco <marco.bzn@gmail.com>
 *         Monaco Davide Giuseppe <black.ralkass@gmail.com>
 *              Petralia Veronica <veronicapetralia@gmail.com>
 *
 * This file is part of DS2011BMP
 *
 * DS2011BMP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DS2011BMP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/**
 * @file tqueuemanager.cpp
 * @author Davide Giuseppe Monaco
 *
 * This file contains TQueueManager class implementation.
 */

#include "tqueuemanager.h"

TQueueManager::TQueueManager(void) { }

TQueueManager::TQueueManager(const Address& addr)
  : _addr(addr), _server(_addr) { }

TQueueManager::~TQueueManager(void) { }

const Address& TQueueManager::getAddr(void) const
{
  return _addr;
}

void TQueueManager::setAddr(const Address& val)
{
  _addr = val;
}

int TQueueManager::enqueue(const TaskDescriptor& ts)
{
  _tQueue.push(ts);
  return 0;
}

TaskDescriptor TQueueManager::dequeue(void)
{
  return _tQueue.pop();
}

void TQueueManager::start(void)
{
  _s_thread = boost::shared_ptr<boost::thread>(
      new boost::thread(
        boost::bind(&TQueueManager::run, this)));

  _s_thread->join();
}

void TQueueManager::run(void)
{
  _server.bind();

  std::cout << "TQueueManager ready..." << std::endl;

  for (;;) {
    char buf[UDPReceiver::MAX_BUF_LEN];
    size_t recv_len;

    recv_len = _server.receive(buf, UDPReceiver::MAX_BUF_LEN);

    boost::shared_ptr<boost::thread>(
        new boost::thread(
          boost::bind(&TQueueManager::serve, this, buf)));
  }
}

void TQueueManager::serve(char *buf)
{
  // stringstream needed for deserialization
  std::stringstream ss_ (std::stringstream::in | std::stringstream::out);

  // create a string, then put it in the stringstream
  std::string received_ (buf);
  ss_ << received_;

  // the new workflow to 'write in'
  TaskDescriptor td_;

  // text_iarchive bound to stringstream
  boost::archive::text_iarchive ia_ (ss_);

  // unserialize, producing a Workflow
  ia_ >> td_;

  // DEBUG
  //std::cout << "Task 0: id: " << td_.getID() << std::endl;

  // enqueue
  this->enqueue(td_);
}
